#include <soar.h>

//#define	THRD_NUM			1
//#define	THRD_NUM			10
//#define	THRD_NUM			100
#define	THRD_NUM			200
#define	TRANSFER_SIZE		(64)

struct thrd_ctl
{/*{{{*/
    unsigned long thrd_id;
	int thrd_idx;
};/*}}}*/

char ip[IP_SIZE+1];

void *thrd_func(struct thrd_ctl *thrd_ctl)
{
    int res;
    int sock;
    char *msg_in=NULL;
    int msg_in_size;
    char *msg_out=NULL;
    int msg_out_size;
    char *ptr;
    int count;
    int loop_qt;
    struct sock_info sock_info;
    
    if((sock=sock_connect(ip, 20000, -1))==INVALID_SOCKET)
    {
        printf("socket connect failed\n");
        goto ERROR_OUT;
    }
    sock_get_info(sock, &sock_info);
    printf("self: %s %d\npeer: %s %d\n",
            sock_info.self_ip, sock_info.self_port,
            sock_info.peer_ip, sock_info.peer_port);

	ALLOC_MULTI(msg_in, char, SOCK_MSG_SIZE, ERROR_OUT);
	ALLOC_MULTI(msg_out, char, SOCK_MSG_SIZE, ERROR_OUT);

#ifdef _MY_MULTI
    memset(msg_in, CHAR0, TRANSFER_SIZE);
	msg_in[TRANSFER_SIZE]=ZERO;

    count=0;
    if(THRD_NUM > 1)
        loop_qt=100000;
    else
        loop_qt=1000000;
    while(count < loop_qt)
    {
        msg_in_size=TRANSFER_SIZE;
#else
    while(fgets(msg_in, SOCK_MSG_SIZE, stdin)!=NULL)
    {
        if((ptr=strchr(msg_in, RTN)))  *ptr=ZERO;
        msg_in_size=strlen(msg_in);
        printf("msg_in(%d): %s\n", msg_in_size, msg_in);
#endif
        if((res=sock_write(sock,
                        (unsigned char *)msg_in, &msg_in_size,
                        -1, WRAP)))
        {
            if(res == RET_ERR_TIMEOUT)
                printf("sock write time out, try again");
            else
                printf("socket write fail errno %d\n", res);
            goto ERROR_OUT;
        }
        if((res=sock_read(sock,
                        (unsigned char *)msg_out, &msg_out_size,
                        -1, WRAP)))
        {
            if(res == RET_ERR_TIMEOUT)
                printf("sock read time out, try again");
            else
                printf("socket read fail errno %d\n", res);
            goto ERROR_OUT;
        }
#ifdef _MY_MULTI
        count++;
        if(count%10000 == 0)
            printf("thread(%d): %d finished\n",
				thrd_ctl->thrd_idx, count);
#else
        msg_out[msg_out_size]=ZERO;
        printf("msg_out(%d):%s\n", msg_out_size, msg_out);
#endif
    }

	FREE(msg_in);
	FREE(msg_out);
    sock_close(sock);    
    printf("Succeed\n");
    return(NULL);

ERROR_OUT:
	FREE(msg_in);
	FREE(msg_out);
    sock_close(sock);    
    printf("Fail\n");
    return(NULL);
}

int main(int argc, char *argv[])
{/*{{{*/
#ifdef _MY_MULTI
	struct thrd_ctl a_thrd_ctl[THRD_NUM];
	int thrd_idx;
#endif

    if(argc==1)  strcpy(ip, "127.0.0.1");
    else  strcpy(ip, argv[1]);

#ifdef _MY_MULTI
	for(thrd_idx=0; thrd_idx<THRD_NUM; thrd_idx++)
	{
		a_thrd_ctl[thrd_idx].thrd_idx=thrd_idx;
		if(thrd_create((THRD_FUNC_T)thrd_func,
                    (void *)&a_thrd_ctl[thrd_idx], 0,
                    &a_thrd_ctl[thrd_idx].thrd_id))
        {
            printf("thrd create fail\n");
            return(-1);
        }
        //sleep(1);
    }
	for(thrd_idx=0; thrd_idx<THRD_NUM; thrd_idx++)
        thrd_join(a_thrd_ctl[thrd_idx].thrd_id);
#else
    thrd_func(NULL);
#endif

    return(0);
}/*}}}*/
